/*--------------------------------------------------------------------------
    This source file is part of Abraxas Game Engine
    For the latest info, see http://code.google.com/abraxasge/
    Copyright (C) 2009, Andrew LeRoy <aleroy@member.igda.org>
    ---

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA  02110-1301, USA.
--------------------------------------------------------------------------*/
//#include "AbxStableHeaders.h"
#include "AbxLogManager.hpp"
#include "AbxException.hpp"
#include "AbxOptions.hpp"
#include <algorithm>


namespace Abx
{
    LogManagerImpl::LogManagerImpl() : defaultLog_(NULL)
    { }

    LogManagerImpl::~LogManagerImpl()
    {
        // Destroy all logs
        LogList::iterator i;
        for (i = logs_.begin(); i != logs_.end(); ++i)
        {
            //ABX_DELETE i->second;
            delete i->second;
        }
    }

    void LogManagerImpl::startup()
    {
        createLog("AbraxasGE.log", true);
    }

    void LogManagerImpl::shutdown()
    {

    }

    Log* LogManagerImpl::createLog(String const& name, bool makeDefault,
                        LogDest writeTo, LogLevel level, LogEntryType entryTypes)
    {
        String absName;

        if (!Options::Instance().empty("Engine.LogPath"))
        {
            absName = Options::Instance().getOption<String>("Engine.LogPath");
        }

        absName.append(name);
        Log* newLog = new Log(absName, writeTo, level, entryTypes);

        if (!defaultLog_ || makeDefault)
        {
            defaultLog_ = newLog;
        }

        logs_.insert(LogList::value_type(name, newLog));

        return newLog;
    }
    
    Log* LogManagerImpl::getLog(String const& name) const
    {
        LogList::const_iterator i = logs_.find(name);
        if (i != logs_.end())
        {
            return i->second;
        }
        else
        {
            ABX_EXCEPT(Exception::ERR_INVALIDPARAMS, "Log not found. ", "LogManager::getLog");
        }
    }

    Log* LogManagerImpl::getDefaultLog() const
    {
        return defaultLog_;
    }
    
    Log* LogManagerImpl::setDefaultLog(Log* log)
    {
        Log* oldLog = defaultLog_;
        defaultLog_ = log;
        return oldLog;
    }

    void LogManagerImpl::setLogLevel(LogLevel level)
    {
        if (defaultLog_)
        {
            defaultLog_->setLogLevel(level);
        }
    }
    
    void LogManagerImpl::setLogEntryTypes(LogEntryType entryTypes)
    {
        if (defaultLog_)
        {
            defaultLog_->setLogEntryTypes(entryTypes);
        }
    }

    void LogManagerImpl::logMessage(String const& message, LogEntryType entryType)
    {
        if (defaultLog_)
        {
            defaultLog_->logMessage(message, entryType);
        }
    }
    
    Log::Stream LogManagerImpl::stream(LogEntryType entryType)
    {
        if (defaultLog_)
            return defaultLog_->stream(entryType);
        else
            ABX_EXCEPT(Exception::ERR_INVALIDPARAMS, "Default log not found. ", "LogManager::stream");
    }
    
    void LogManagerImpl::destroyLog(String const& name)
    {
        LogList::iterator i = logs_.find(name);
        if (i != logs_.end())
        {
            if (defaultLog_ == i->second)
            {
                defaultLog_ = 0;
            }
            delete i->second;
            logs_.erase(i);
        }

        // Set another default log if this one removed
        if (!defaultLog_ && !logs_.empty())
        {
            defaultLog_ = logs_.begin()->second;
        }
    }

    void LogManagerImpl::destroyLog(Log* log)
    {
        destroyLog(log->getName());
    }
} // namespace Abx
